﻿namespace Blaze.ConfigExportTool.Serialization
{
    using System;
    using System.Reflection;

    /// <summary>
    /// 提供将对象序列化到流的功能。
    /// </summary>
    public class PythonSerializer : SerializerBase
    {
        public PythonSerializer(Type targetType)
            : base(targetType)
        {
        }

        /// <summary>
        /// 获取数组数据块。
        /// </summary>
        protected override Block GetCollectionBlock(bool newLine)
        {
            return new Block(this, "[", "]", newLine);
        }

        /// <summary>
        /// 获取字典数据块。
        /// </summary>
        protected override Block GetMapBlock(bool newLine)
        {
            return new Block(this, "{", "}", newLine);
        }

        /// <summary>
        /// 当需要序列化时调用此方法。
        /// </summary>
        /// <param name="target">需要序列化的对象</param>
        protected override void OnSerialize(object target)
        {
            WriteLine("# -*- coding: utf-8 -*-");
            WriteLine("data = \\");
            using (new Indentation(this))
            {
                Write(TargetType, target);
            }
            WriteLine();
        }

        /// <summary>
        /// 写入赋值符号。 如：在lua中为"="，在python中为":"。
        /// </summary>
        protected override void WriteAssignmentSymbol()
        {
            Writer.Write(": ");
        }

        /// <summary>
        /// 写入字段名。
        /// </summary>
        protected override void WriteFieldName(string fieldName)
        {
            Writer.Write("\"");
            Writer.Write(fieldName);
            Writer.Write("\"");
        }

        /// <summary>
        /// 写入类型为<see cref="bool"/>的字段的值。
        /// </summary>
        /// <param name="value">字段的值</param>
        protected override void WriteFieldValue(bool value)
        {
            if (value)
                Writer.Write("True");
            else
                Writer.Write("False");
        }

        /// <summary>
        /// 写入Map的键。
        /// </summary>
        protected override void WriteMapKey(object instance, FieldInfo fieldInfo)
        {
            var value = fieldInfo.GetValue(instance);
            WritePrimitiveField(fieldInfo.FieldType, value);
        }
    }
}